import { Example, UiFrameworkExtension, CommunityNote } from '../../components'
import { Link } from '@brillout/docpress'

<CommunityNote tool="styled-jsx" url="https://github.com/vercel/styled-jsx" hasExtension="react" />

## Manual integration

If you use <Link href="/vike-react">`vike-react`</Link>, you can manually integrate `styled-jsx` by using:
- <Link href="/onBeforeRenderHtml" doNotInferSectionTitle />
- <Link href="/Wrapper" doNotInferSectionTitle />
- <Link href="/onAfterRenderHtml" doNotInferSectionTitle />

Example:
 - <Example timestamp="2024.12" repo="phonzammi/vike-react-styled-jsx-example" />

## Without `vike-react`

To use Vike with `styled-jsx` without <UiFrameworkExtension name list={['vike-react']} />:

1. Install:

   ```shell
   npm install styled-jsx
   ```

2. Add `styled-jsx` to `vite.config.ts`:

   ```ts
   // vite.config.ts

   import type { UserConfig } from 'vite'
   import react from '@vitejs/plugin-react'
   import vike from 'vike/plugin'

   export default {
     plugins: [react({ babel: { plugins: ['styled-jsx/babel'] } }), vike()]
   } satisfies UserConfig
   ```

3. Collect and inject styles.
   > When using a CSS-in-JS tool, like `styled-jsx`, you always need to collect the page's styles upon SSR in order <Link href="/css-in-js">to avoid FOUC</Link>.

   ```tsx
   // /renderer/+onRenderHtml.tsx

   export { onRenderHtml }

   import React from 'react'
   import { renderToString, renderToStaticMarkup } from 'react-dom/server'
   import { escapeInject, dangerouslySkipEscape } from 'vike/server'
   import { Layout } from './Layout'
   import { createStyleRegistry, StyleRegistry } from 'styled-jsx'
   import type { PageContextServer } from 'vike/types'

   const registry = createStyleRegistry()

   async function onRenderHtml(pageContext: PageContextServer) {
     // flush styles to support the possibility of concurrent rendering
     registry.flush()

     const { Page } = pageContext
     // include the styleregistry in the app render to inject the styles
     const viewHtml = dangerouslySkipEscape(
       renderToString(
         <StyleRegistry registry={registry}>
           <Layout>
             <Page />
           </Layout>
         </StyleRegistry>
       )
     )

     // extract the styles to add as head tags to the server markup
     const headTags = renderToStaticMarkup(<>{registry.styles()}</>)

     return escapeInject`<!DOCTYPE html>
       <html>
         <head>
           ${dangerouslySkipEscape(headTags)}
         </head>
         <body>
           <div id="root">${viewHtml}</div>
         </body>
       </html>`
   }
   ```

Example:
 - <Example timestamp="2023.07" repo="jeremypress/vite-ssr-styled-jsx" />
   > vite-plugin-ssr was the [previous name of Vike](https://vite-plugin-ssr.com/vike).

## See also

- <Link href="/css-in-js" doNotInferSectionTitle />
- [styled-jsx README > Server Side Rendering](https://github.com/vercel/styled-jsx#server-side-rendering)
